//
//  ViewController.m
//  NScodingAndNscoping
//
//  Created by wanglei on 16/12/25.
//  Copyright © 2016年 wanglei. All rights reserved.
//

#import "ViewController.h"
#import "Model1.h"

@interface ViewController ()
@property(nonatomic,strong)Model1 *model;

// 首先分别给出copy和strong修饰的属性，以NSString举例
// 1、strong
//@property (nonatomic, strong) NSString *str;
// 2、copy
@property (nonatomic, copy) NSString *str;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self judgeCopy];
//    [self myCopy];
//    [self doubleCopy];
//    [self deepCopyCompletely];
//    [self gleanings];
}


/**
 拾遗
 */
- (void)gleanings{

    // 分别对1和2执行下述代码
    NSMutableString *mutableStr = [NSMutableString stringWithFormat:@"123"];
    self.str = mutableStr;
    [mutableStr appendString:@"456"];
    NSLog(@"%@", self.str);
    NSLog(@"%p", self.str);
    NSLog(@"%@", mutableStr);
    NSLog(@"%p", mutableStr);
    
}

/**
 完全深拷贝
 */
- (void)deepCopyCompletely{
    
    // 随意创建一个NSMutableString对象
    NSMutableString *mutableString = [NSMutableString stringWithString:@"1"];
    // 随意创建一个包涵NSMutableString的NSMutableArray对象
    NSMutableString *mutalbeString1 = [NSMutableString stringWithString:@"1"];
    NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:mutalbeString1, nil];
    // 将mutableString和mutableArr放入一个新的NSArray中
    NSArray *testArr = [NSArray arrayWithObjects:mutableString, mutableArr, nil];
    // 通过归档、解档方式创建copy
    NSArray *testArrCopy = [NSKeyedUnarchiver unarchiveObjectWithData:
                            [NSKeyedArchiver archivedDataWithRootObject:testArr]];
    
    // testArr和testArrCopy指针对比
    NSLog(@"%p", testArr);
    NSLog(@"%p", testArrCopy);
    
    // testArr和testArrCopy中元素指针对比
    // mutableString对比
    NSLog(@"%p", testArr[0]);
    NSLog(@"%p", testArrCopy[0]);
    // mutableArr对比
    NSLog(@"%p", testArr[1]);
    NSLog(@"%p", testArrCopy[1]);
    
    // mutableArr中的元素对比，即mutalbeString1对比
    NSLog(@"%p", testArr[1][0]);
    NSLog(@"%p", testArrCopy[1][0]);
    
}

/**
 双层深copy
 */
- (void)doubleCopy{
    
    // 随意创建一个NSMutableString对象
    NSMutableString *mutableString = [NSMutableString stringWithString:@"1"];
    // 随意创建一个包涵NSMutableString的NSMutableArray对象
    NSMutableString *mutalbeString1 = [NSMutableString stringWithString:@"1"];
    Model1 *model = [[Model1 alloc]init];
    model.a = 1;
    self.model = [model copy];
    NSMutableArray *mutableArr = [NSMutableArray arrayWithObjects:mutalbeString1,_model, nil];
    // 将mutableString和mutableArr放入一个新的NSArray中
    NSArray *testArr = [NSArray arrayWithObjects:mutableString, mutableArr, nil];
    // 通过官方文档提供的方式创建copy
    NSArray *testArrCopy = [[NSArray alloc] initWithArray:testArr copyItems:YES];
    
    // testArr和testArrCopy指针对比
    NSLog(@"%p", testArr);
    NSLog(@"%p", testArrCopy);
    
    // testArr和testArrCopy中元素指针对比
    // mutableString对比
    NSLog(@"%p", testArr[0]);
    NSLog(@"%p", testArrCopy[0]);
    // mutableArr对比
    NSLog(@"%p", testArr[1]);
    NSLog(@"%p", testArrCopy[1]);
    
    // mutableArr中的元素对比，即mutalbeString1对比
    NSLog(@"%p", testArr[1][0]);
    NSLog(@"%p", testArrCopy[1][0]);
    NSLog(@"%@",testArr[1][1]);
}
/**
 对自定义对象的深浅拷贝的探究
 */
- (void)myCopy{
    
    Model1 *model = [[Model1 alloc] init];
    Model1 *copyModel = [model copy];
    
    NSLog(@"%ld,%@", (long)model.a,model);
    //打印结果说明是浅拷贝
    NSLog(@"%ld,%@", (long)copyModel.a,copyModel);
}
/**
 此方法的目的的判断深浅拷贝的原则
 
 对immutableObject，即不可变对象，执行copy，会得到不可变对象，并且是浅copy。
 对immutableObject，即不可变对象，执行mutableCopy，会得到可变对象，并且是深copy。
 对mutableObject，即可变对象，执行copy，会得到不可变对象，并且是深copy。
 对mutableObject，即可变对象，执行mutableCopy，会得到可变对象，并且是深copy。
*/
- (void)judgeCopy{
    // 此处以NSString为例探究框架类深浅copy
    
    // 不可变对象
    NSString *str = @"1";
    NSString *str1 = [str copy];
    NSString *str2 = [str mutableCopy];
    
    // 可变对象
    NSMutableString *mutableStr = [NSMutableString stringWithString:@"1"];
    NSMutableString *mutableStr1 = [mutableStr copy];
    NSMutableString *mutableStr2 = [mutableStr mutableCopy];
    
    // 打印对象的指针来确认是否创建了一个新的对象
    // 不可变对象原始指针
    NSLog(@"str = %p", str);
    // 不可变对象copy后指针
    NSLog(@"str1 = %p", str1);
    // 不可变对象mutalbeCopy后指针
    NSLog(@"str2 = %p", str2);
    
    // 可变对象原始指针
    NSLog(@"mutableStr = %p", mutableStr);
    // 可变对象copy后指针
    NSLog(@"mutableStr1 = %p", mutableStr1);
    // 可变对象mutalbeCopy后指针
    NSLog(@"mutableStr2 = %p", mutableStr2);
    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
